<?php

class SendMail {
	
	/**
	 * stores all TO addresses
	 *
	 * @access	public
	 * @var		string 
	 */
	var $to = '';
  
	/**
	 * stores all CC addresses
	 *
	 * @access	public
	 * @var 		string 
	 */ 
	var $cc = '';
  
	/**
	 * stores all BCC addresses
	 *
	 * @access	public
	 * @var		string 
	 */
	var $bcc = '';
	
	/**
	 * stores FROM address
	 *
	 * @access	public
	 * @var		string 
	 */
	var $from = '';
	
	/**
	 * stores REPLY TO address
	 *
	 * @access	public
	 * @var		string 
	 */
	var $replyTo = '';
  
	/**
	 * stores Subject
	 *
	 * @access	public
	 * @var		string 
	 */
	var $subject = '';
  
	/**
	 * contains template type
	 *
	 * @access	public
	 * @var		string 
	 */
	var $mailType = '';
	  
	/**
	 * contains mail data
	 *
	 * @access	public
	 * @var		string 
	 */
	var $mailData = array();
  
	/**
	 * contains generated email body
	 *
	 * @access	public
	 * @var		string 
	 */
	var $email = '';
  
	/**
	 * anyDB handler
	 *
	 * @access	private
	 * @var			object
	 */
	var $anydb;
  
	/**
	 * mail types' table
	 *
	 * @access	private
	 * @var		string 
	 */
	var $mailTypeTable = 'mails_all_mail_types';
  
	/**
	 * mail templates' table
	 *
	 * @access	private
	 * @var		string 
	 */
	var $mailsTable = 'mails';
	
	/**
	 * mail queue table
	 *
	 * @access	private
	 * @var		string 
	 */
	var $mailsQueueTable = 'mails_queue';
	
	/**
	 * mail queue data table
	 *
	 * @access	private
	 * @var		string 
	 */
	var $mailsQueueDataTable = 'mails_queue_data';
	
	/**
	 * mail queue sections table
	 *
	 * @access	private
	 * @var		string 
	 */
	var $mailsQueueSectionsTable = 'mails_queue_sections';
  
	/**
	 * base store name
	 *
	 * @access	public
	 * @var		string 
	 */
	var $baseStoreName = '';
  
	/**
	 * base support email
	 *
	 * @access	public
	 * @var		string
	 */
	var $baseSupportEmail = 'support@propersupport.com';
  
	/**
   * error/debug object
	 *
	 * @access	public
	 * @var		string
	 */
	var $error;
	
	/**
  	 * error/debug object
	 *
	 * @access	public
	 * @var		string
	 */
	var $displayErrors = false;
  
	/**
	 * XML sections
	 *
	 * @access	private
	 * @var		string 
	 */
	var $includeXMLSections = array ('header', 'footer', 'data', 'body');
	
	/**
	 * Return type of the body section
	 *
	 * @access	public
	 * @var		string 
	 */
	var $returnType = 'members';
	
	/**
	 * Keeps the last inserted mail id
	 *
	 * @access	public
	 * @var		string 
	 */
	var $lastInsertMailId;
	
	/**
	 * This class is a bunch of methods which allow sending an email through the email template system
	 *
	 * @access   public
	 * @author   Svilen <svilen@svilen.com>
	 *
	 * @see 									Error class
	 *
	 * @since    20-09-2005
	 * @version  1.2
	 *
	 */
	function SendMail ($dbHandler, $baseStoreName, $baseSupportEmail) {
		// Initialize error handler
		$this->error = new Error();
		
		if (empty($dbHandler)) {
			$this->error->addError(1, 'Mail requires anydb handler to be passed', FATAL_ERROR, $this->displayErrors);
		}
		
		// add db handler
		$this->anydb = $dbHandler;
		
		// base store name
		$this->baseStoreName = $baseStoreName;
		
		// base support email
		$this->baseSupportEmail = $baseSupportEmail;
	}
	
	/**
	 * This method adds automatically custom keywords, which are available in all email templates.
	 *
	 * @access   private
	 * @author   Svilen <svilen@svilen.com>
	 *
	 * @param    array   $mailData		Mail data array
	 *
	 * @return   array						Returns array with custom keywords
	 *
	 * @see 		 getEmail()
	 * @since    21-09-2005
	 * @version  1.0
	 *
	 */
	function customKeywords ($mailData) {
		// custom keywords
		$customKeywords = array(
			'storename' => ucwords($this->getStoreNameByUsername($mailData['mainusername'])),
			'fullname'	=>	ucwords($this->getFullNameByUsername($mailData['mainusername'])),
		);
		
		return $customKeywords;
	}
	
	/**
	 * This method retrieves store name by client username.
	 *
	 * @access   private
	 * @author   Svilen <svilen@svilen.com>
	 *
	 * @param    string $username			Client's username
	 *
	 * @return   string						Store name
	 *
	 * @since    21-09-2005
	 * @version  1.0
	 *
	 */
	function getStoreNameByUsername ($username) {
		$username = $this->anydb->escapeStr($username);
	
		$query = <<<echo
SELECT title FROM stores, resellers, clients WHERE clients.username = '$username' AND clients.reseller_id = resellers.reseller_id AND stores.reseller_id = resellers.reseller_id
echo;
	
		$this->anydb->query($query);
		
		if (empty($this->anydb->error) ) {
			$name = $this->anydb->getValue();
		}
		
		return($name);
	}
	
	/**
	 * This method retrieves client's fullname by given username
	 *
	 * @access   private
	 * @author   Svilen <svilen@svilen.com>
	 *
	 * @param    string $username		Clients's username
	 *
	 * @return   string					Client's fullname
	 *
	 * @since    21-09-2005
	 * @version  1.0
	 *
	 */
	function getFullNameByUsername ($username) {
		$username = $this->anydb->escapeStr($username);
		$fullname = '';
	
		$query = <<<echo
SELECT firstname, lastname FROM clients WHERE clients.username = '$username'
echo;
	
		$this->anydb->query($query);
		
		if (empty($this->anydb->error) ) {
			$recordSet = $this->anydb->getNext();
			
			$fullname = $recordSet['firstname'].' '.$recordSet['lastname'];
		}
		
		return($fullname);
	}
	
	/**
	 * This class method generates the email which should be send
	 *
	 * @access   public
	 * @author   Svilen
	 *
	 * @param    string   $mailData  The input string which will be parsed and cleaned up
	 * @param    boolean  $mailType  TRUE if the string should be escaped for DB query
	 * @param    string   $variable	unique sting (store_id, reseller_id, default) which identifies who is the owner of the email template  
	 * @param    integer  $value			Owner unique id
	 *
	 * @return   array               Returns email details
	 *
	 * @since    14-09-2005
	 * @version  1.01
	 *
	 */
	function getEmail($mailData = array(), $mailType, $variable = 'default', $value = 0, $includeXMLSections = array(), $returnType = '') {
		$email = array();
		$variable = strtolower($variable);
		
		// Add custom set keywords for all templates
		$mailData = array_merge($this->customKeywords($mailData), $mailData);
		
		// check mail type
		if (!$this->isAvailableMailType($mailType)) {
			$this->error->addError(2, 'SendMail: "'.$mailType.'" is not supported', FATAL_ERROR, $this->displayErrors);
		}
		
		// Assign mail type to the appropriate property
		$this->mailType = $mailType;
		// Assign returnType
		$this->returnType = !empty($returnType) ? $returnType : $this->returnType;
		// Assign which XML Section do we need
		$includeXMLSections = array_unique(array_merge($this->includeXMLSections, $includeXMLSections));
		$includeXMLSections = array_map ('strtolower', $includeXMLSections);
		// assign validated mail data to the storage
		$this->mailData = $this->validateData($mailData);
		
		// Set correct from name
		$fromNameStore = $this->getStoreNameByUsername($mailData['mainusername']);
		$this->baseStoreName = !empty($fromNameStore) ? $fromNameStore : $this->baseStoreName;
		
		// fetch email template
		$template = $this->fetchTemplate($this->mailType, $variable, $value, $includeXMLSections);
    	
		// Replace special keywords in body and subject
		if (!empty($template)) {
			// Make keywords in our format look like from $hash[kwd]=val to $hash["%kwd%"] = val;
			foreach ($this->mailData as $kwd => $val) {
				if (!preg_match("/^\%$kwd\%$/", $kwd)) {
					$this->mailData["%$kwd%"] = $val;
					unset($this->mailData[$kwd]);
				}
			}
      	
			$Subject = $template['subject'];
			$Body    = $this->parseBody($template['content'], $includeXMLSections);
			$Mime    = $template['mime_type'];
			
			$Subject = strtr($Subject, $this->mailData);
    
			// When i have struct type to return, $Body is array
			if (is_array($Body)) {
				foreach ($Body as $index => $item) {
					$Body[$index]['data'] = strtr($item['data'], $this->mailData);
				}
			}
			else {
				$Body = strtr($Body, $this->mailData);
			}
			
			$email = array(
				'subject' 		=> $Subject, 
				'body'    		=> $Body, 
				'mime_type'    => $Mime, 
				'from'    		=> ((empty($template['from_name'])) ? $this->baseStoreName : $template['from_name']).' <'.$this->baseSupportEmail.'>'
			);
		}
    	
		// assign created email
		$this->email = $email;
		// return created email
		return $email;
  }
  
	/**
	 * This class method fetches correct email template from the db
	 * Priority for fetching mail template is:
	 * 1. Store
	 * 2. Reseller
	 * 3. Default
	 *    
	 * @access   private
	 * @author   Svilen
	 *
	 * @param    boolean  $mailType  TRUE if the string should be escaped for DB query
	 * @param    string   $variable	unique sting (store_id, reseller_id, default) which identifies who is the owner of the email template  
	 * @param    integer  $value			Owner unique id
	 *
	 * @return   array               Returns email template array
	 *
	 * @since    14-09-2005
	 * @version  1.0
	 *
	 */
	function fetchTemplate($mailType, $variable, $value, $includeXMLSections) {
		$from_name = '';
		
		$query = 'SELECT subject, content, mime_type, mail_type, variable, value FROM '.$this->mailsTable.' WHERE ';
		
		// Try to fetch template for store_id first
		if ($variable == 'store_id') {
			$this->anydb->query($query."variable = '$variable' AND  value = '$value' AND mail_type = '$mailType'");
			$result = $this->anydb->getNext();
		}
		
		$from_name = $this->getStoreName($value);
				
		// When there is NO result for store_id we get reseller_id and try to get template for reseller
		if (empty($result)) {
			$variable = 'reseller_id';
			$value    = $this->getResellerId($value); // Here $value in argument is still STORE_ID
		}
		
		// Fetch template for reseller_id;
		if ($variable == 'reseller_id') {
			$this->anydb->query($query."variable = '$variable' AND value = '$value' AND mail_type = '$mailType'");
			$result = $this->anydb->getNext();
		}
		
		if (empty($from_name)) {
			$from_name = $this->getResellerName($value);
		}
        
		// If statements above are failed we fetch default template for this mail_type
		if (empty($result)) {
			$variable = 'default';
			$value    = 0;
			
			$this->anydb->query($query."variable = '$variable' AND  value = '$value' AND mail_type = '$mailType'");
			$result = $this->anydb->getNext();
		}
    
		// Unescape strings
		$result['subject'] = stripslashes(trim($result['subject']));
		$result['content'] = stripslashes($result['content']);
		$result['mime_type'] = stripslashes(trim($result['mime_type']));
		
		$result['from_name'] = $from_name;
				
		return ($result);
	}
  
	/**
	 * This method validates mailData array
	 *
	 * @access   private
	 * @author   Svilen <svilen@svilen.com>
	 *
	 * @param    array   $mail_data   Mail data array
	 *
	 * @return   array   Correct mail data array
	 *
	 * @since    14-09-2005
	 * @version  1.0
	 *
	 */
	function validateData ($mail_data) {
		if (empty($mail_data) || !is_array($mail_data)) {
			$mail_data = array();
		}
		
		return $mail_data;
	}
  
	/**
	 * This method tells that mail is available or not. It returns BOOLEAN.
	 * Usage:
	 *  if (isAvailableMailType($mail_type)) {
	 *      echo "Mail type \"$mail_type\" is Ok<br>\n";
	 *  } else {
	 *      echo "Bad mail type - $mail_type<br>\n";
	 *  }
	 *
	 * @access   private
	 * @author   weby, added to the SendMail class by Svilen
	 *
	 * @param    string   $mail_type         The input string which will be parsed and cleaned up
	 *
	 * @return   boolean
	 *
	 * @since    14-09-2005
	 * @version  1.0
	 *
	 */
	function isAvailableMailType ($mail_type) {
		if (!empty($mail_type)) {
			// make em lower because the records in DB are all LC(*)-ed
			$mail_type = strtolower($mail_type);
			
			$query = "SELECT COUNT(mail_type) AS mail_types FROM $this->mailTypeTable WHERE mail_type = '$mail_type'";
			$this->anydb->query($query);
			
			if (empty($this->anydb->error)) {
				$result = $this->anydb->getValue();
				
				if ($result > 0) {
					return(true);
				}
			}
		}
		
		return(false);
	}
  
	/**
	 * This method retrieves store name.
	 *
	 * @access   private
	 * @author   weby, added to the SendMail class by Svilen
	 *
	 * @param    integer   $store_id         The store_id of the store
	 *
	 * @return   string											Store name
	 *
	 * @since    14-09-2005
	 * @version  1.1
	 *
	 */
	function getStoreName ($store_id) {
		$store_id = (int) $this->anydb->escapeStr($store_id);
	
		$query = <<<echo
SELECT title FROM stores WHERE store_id = $store_id
echo;
	
		$this->anydb->query($query);
		
		if (empty($this->anydb->error) ) {
			$name = $this->anydb->getValue();
		}
		
		return($name);
	}
  
	/**
	 * This method fetches reseller_id by given store_id
	 *
	 * @access   private
	 * @author   weby, added to the SendMail class by Svilen
	 *
	 * @param    integer   $store_id      The store_id of the store
	 *
	 * @return   integer									 Reseller id
	 *
	 * @since    14-09-2005
	 * @version  1.1
	 *
	 */
	function getResellerId ($store_id) {
		$store_id = (int) $this->anydb->escapeStr($store_id);
		
		$query = <<<echo
SELECT reseller_id FROM stored WHERE store_id = $store_id
echo;
		$this->anydb->query($query);
		
		if (empty($this->anydb->error)) {
			return $this->anydb->getValue();
		}
		
		return(false);
	}
  
	/**
	 * This method retrieves reseller name.
	 *
	 * @access   private
	 * @author   weby, added to the SendMail class by Svilen
	 *
	 * @param    integer   $reseller_id		The reseller_id of the store
	 *
	 * @return   string							Reseller name
	 *
	 * @since    14-09-2005
	 * @version  1.1
	 *
	 */
	function getResellerName ($reseller_id) {
		$reseller_id = (int) $this->anydb->escapeStr($reseller_id);
	
		$query = <<<echo
SELECT first_name, last_name FROM resellers WHERE reseller_id = $reseller_id
echo;
		$this->anydb->query($query);
	
		if (empty($this->anydb->error)) {
			$result = $this->anydb->getNext();
			
			if (!empty($result)) {
				$name = implode(' ', $result);
			}
		}
		
		return($name);
	}
  
	/**
	 * This method retrieves reseller name.
	 *
	 * @access   private
	 * @author   weby, added to the SendMail class by Svilen
	 *
	 * @param    string   $body      						message body as string
	 * @param    array    $includeXMLSections    		Array contains name of blocks to show, default is mail
	 *																	default values are: header, footer, data
	 * @param    string   $returnType      				admin   - Array("subject"=>$Subject, "body"=>$Body, "mime"=>$Mime)
	 *																	members - Array("subject"=>$Subject, "body"=>$Body, "mime"=>$Mime)
	 *																	mail    - Array("subject"=>$Subject, "body"=>$Body, "mime"=>$Mime)
	 *																	struct  - wryshta hash:
	 * Array
	 * (
	 *     [subject] => Welcome to SupremeServer.
	 *     [body] => Array
	 *         (
	 *             [HEADER] => Array
	 *                 (
	 *                     [opts] =>
	 *                     [data] => Dear Valued Customer
	 *                 )
	 *
	 *             [BODY] => Array
	 *                 (
	 *                     [opts] =>
	 *                     [data] =>
	 *                 )
	 *             [FOOTER] => Array
	 *                 (
	 *                     [opts] => Array
	 *                         (
	 *                             [EDIT] => 1
	 *                         )
	 *
	 *                     [data] => data
	 *                 )
	 *
	 *         )
	 *
	 *     [mime] => text/plain
	 *     [from] => SupremeServer
	 * )
	 *
	 * @return   string		Depends on the $returnType
	 *
	 * @since    15-09-2005
	 * @version  1.1
	 *
	 */
	function parseBody ($body, $includeXMLSections) {
		$Content = array();
		$values = array();
		$index = array();
		$skey = '';
				
		$xml_parser = xml_parser_create();
		xml_parse_into_struct($xml_parser, $body, $values, $index);	
		xml_parser_free($xml_parser);
				
		if (is_array($values)) {			
			foreach ($values as $skey => $vals) {
				if (strtolower($vals["type"])!="complete") {
					continue;
				}
  				
				switch ($this->returnType) {
					case 'admin':
						$Content[$vals['tag']] = $vals['value'];
					break;
					case 'members':
						if ($vals['attributes']['HIDDEN'] == 1) {
							continue;
						}
						if ($vals['attributes']['EDIT'] == 1) {
							$Content[] = "<textarea cols=80 rows=5 name='arr[$vals[tag]]'>" . htmlspecialchars($vals['value']) . "</textarea>";
							continue;
						}
						// $Content[] = '<pre>' . $vals['value'] . '</pre>';
						// $Content[] = $vals['value'];
						if (in_array(strtolower($vals['tag']), $includeXMLSections)) {
							$Content[] = $vals['value'];
						}
						break;
					case "mail":
						if ($vals['attributes']['HIDDEN'] == 1) {
							continue;
						}
						/*
						if ($includeXMLSections[$vals['tag']]) {
							$Content[] = $vals['value'];
						}
						*/
						if (in_array(strtolower($vals['tag']), $includeXMLSections)) {
							$Content[] = $vals['value'];
						}
						break;
					default:
						$Content[$vals['tag']]['opts'] = $vals['attributes'];
						$Content[$vals['tag']]['data'] = stripslashes($vals['value']);
						break;
				}
			}
			
			if ($this->returnType == 'struct') {
				return $Content;
			}
			else {
				return join('', $Content);
			}
		}
    
		return $Content;
	}
  
	/**
	 * This class method generates the email which should be send
	 *
	 * @access   public
	 * @author   Svilen
	 *
	 * @param    string   $to  		The TO string
	 * @param    string   $cc  		The CC string
	 * @param    string   $bcc 		The BCC string
	 * @param    string   $mailData  The input string which will be parsed and cleaned up
	 * @param    boolean  $mailType  TRUE if the string should be escaped for DB query
	 * @param    string   $variable	unique sting (store_id, reseller_id, default) which identifies who is the owner of the email template  
	 * @param    integer  $value		Owner unique id
	 * @param    string   $from 		The FROM string
	 *
	 * @return   boolean					Returns mail id if email is successfully inserted into the mails queue or FALSE on fail
	 *
	 * @since    19-09-2005
	 * @version  1.0
	 *
	 */
	function Send ($to, $cc, $bcc, $mailData = array(), $mailType, $variable = 'default', $value = 0, $includeXMLSections = array(), $from = null, $replyTo = null) {
		
		// assign TO addresses
		$this->to = $to;
		// assign CC addresses
		$this->cc = $cc;
		// assign BCC addresses
		$this->bcc = $bcc;
		// mails data
		$mailDataQuery = '';
		// mails sections
		$mailSectionsQuery = '';
		// check
		$value = (int) $value;
		// set $from
		if (!empty($from)) {
			$this->from = $from;
		}
		// set $replyTo
		if (!empty($replyTo)) {
			$this->replyTo = $replyTo;
		}
		
		// To is compulsory
		if (empty($to)) {
			return false;
		}
		
		// generate mail data query
		foreach ($mailData as $key => $val) {
			$mailDataQuery .= "INSERT INTO $this->mailsQueueDataTable (mails_queue_id, keyword, value) VALUES ((SELECT CURRVAL('mails_queue_mails_queue_id_seq')), '".$this->anydb->escapeStr($key)."', '".$this->anydb->escapeStr($val)."');";
		}
		
		// generate mail sections query
		foreach ($includeXMLSections as $key1 => $val1) {
			if (!empty($val1)) {
				$mailSectionsQuery .= "INSERT INTO $this->mailsQueueSectionsTable (mails_queue_id, section) VALUES ((SELECT CURRVAL('mails_queue_mails_queue_id_seq')), '".$this->anydb->escapeStr($val1)."');";
			}
		}
		
		$query = "BEGIN;
					INSERT INTO $this->mailsQueueTable (to_string, cc_string, bcc_string, from_string, reply_to_string, mail_type, variable, value) VALUES ('".$this->anydb->escapeStr($this->to)."', '".$this->anydb->escapeStr($this->cc)."', '".$this->anydb->escapeStr($this->bcc)."', '".$this->anydb->escapeStr($this->from)."', '".$this->anydb->escapeStr($this->replyTo)."', '".$this->anydb->escapeStr($mailType)."', '".$this->anydb->escapeStr($variable)."', '".$this->anydb->escapeStr($value)."');
					$mailDataQuery
					$mailSectionsQuery
					COMMIT;";
		
		// insert mail into the queue table
		$this->anydb->query($query);
		
		if (empty($this->anydb->error)) {
			// Get last inserted mail Id
			$this->anydb->query("SELECT CURRVAL('mails_queue_mails_queue_id_seq')");
			$this->lastInsertMailId = $this->anydb->getValue();
			
			return $this->lastInsertMailId;
		}
		else {
			return false;	
		}
	}
	
	/**
	 * This class method generates the sql query which should be inserted on verdi1
	 *
	 * @access   public
	 * @author   Svilen <svilen@svilen.com>
	 *
	 * @param    string   $to  		The TO string
	 * @param    string   $cc  		The CC string
	 * @param    string   $bcc 		The BCC string
	 * @param    string   $mailData  The input string which will be parsed and cleaned up
	 * @param    boolean  $mailType  TRUE if the string should be escaped for DB query
	 * @param    string   $variable	unique sting (store_id, reseller_id, default) which identifies who is the owner of the email template  
	 * @param    integer  $value		Owner unique id
	 * @param    string   $from 		The FROM string
	 *
	 * @return   boolean					Returns sql query which should be inserted on verdi1 or FALSE on fail
	 *
	 * @since    21-09-2005
	 * @version  1.1
	 *
	 */
	function SQLQuerySend($to, $cc, $bcc, $mailData = array(), $mailType, $variable = 'default', $value = 0, $includeXMLSections = array(), $from = null, $replyTo = null) {
		// assign TO addresses
		$this->to = $to;
		// assign CC addresses
		$this->cc = $cc;
		// assign BCC addresses
		$this->bcc = $bcc;
		// mails data
		$mailDataQuery = '';
		// mails sections
		$mailSectionsQuery = '';
		// check
		$value = (int) $value;
		// set $from
		if (!empty($from)) {
			$this->from = $from;
		}
		// set $replyTo
		if (!empty($replyTo)) {
			$this->replyTo = $replyTo;
		}
		
		// To is compulsory
		if (empty($to)) {
			return false;
		}
		
		// generate mail data query
		foreach ($mailData as $key => $val) {
			$mailDataQuery .= "INSERT INTO $this->mailsQueueDataTable (mails_queue_id, keyword, value) VALUES ((SELECT CURRVAL('mails_queue_mails_queue_id_seq')), '".$this->anydb->escapeStr($key)."', '".$this->anydb->escapeStr($val)."');";
		}
		
		// generate mail sections query
		foreach ($includeXMLSections as $key1 => $val1) {
			if (!empty($val1)) {
				$mailSectionsQuery .= "INSERT INTO $this->mailsQueueSectionsTable (mails_queue_id, section) VALUES ((SELECT CURRVAL('mails_queue_mails_queue_id_seq')), '".$this->anydb->escapeStr($val1)."');";
			}
		}
		
		$query = "INSERT INTO $this->mailsQueueTable (to_string, cc_string, bcc_string, from_string, reply_to_string, mail_type, variable, value) VALUES ('".$this->anydb->escapeStr($this->to)."', '".$this->anydb->escapeStr($this->cc)."', '".$this->anydb->escapeStr($this->bcc)."', '".$this->anydb->escapeStr($this->from)."', '".$this->anydb->escapeStr($this->replyTo)."', '".$this->anydb->escapeStr($mailType)."', '".$this->anydb->escapeStr($variable)."', '".$this->anydb->escapeStr($value)."'); $mailDataQuery $mailSectionsQuery";
		
		return $query;
	}
	
	/**
	 * This method sends all queued emails that are newer than now() - given days
	 *
	 * @access   public
	 * @author   Svilen <svilen@svilen.com>
	 *
	 * @param    integer		$newerThan	Mail data array
	 *
	 * @return   boolean   					Returns TRUE on success or FALSE on fail
	 *
	 * @since    21-09-2005
	 * @version  1.1
	 *
	 */
	function SendMailsFromQueue ($newerThan = 10) {
		$newerThan = (int) $this->anydb->escapeStr($newerThan);
		$mailId = false;
		$mailIds = array();
		
		// get newly inserted not send mails
		$query = <<<echo
SELECT mails_queue_id as mail_id FROM $this->mailsQueueTable WHERE sent = FALSE AND timestamp_create > (NOW() - interval '$newerThan day');
echo;
		$this->anydb->query($query);
		
		// if there is an error - halt
		if (!empty($this->anydb->error)) {
			return false;	
		}
		
		// get all ids of the mails which will be sent
		$mailIds = $this->anydb->getAll();
		
		foreach ($mailIds as $key => $value) {
			$mailId = $value['mail_id'];
			$sent = false;
			
			$sent = $this->SendMailFromQueue($mailId);
			
			// raise an error
			if ($sent == false) {
				$this->error->addError(1, 'SendMailsFromQueue() died on mail Id: '.$mailId, FATAL_ERROR, $this->displayErrors);
				return false;	
			}
		}
		
		return true;
	}
	
	/**
	 * This method sends a queued emails that are newer than now() - given days
	 *
	 * @access   public
	 * @author   Svilen <svilen@svilen.com>
	 *
	 * @param    integer		$mailId	Mail Id indicating the email message in the queue, which should be sent
	 *
	 * @return   boolean   				Returns TRUE on success or FALSE on fail
	 *
	 * @since    19-09-2005
	 * @version  1.0
	 *
	 */
	function SendMailFromQueue ($mailId) {
		$mail = array();
		$mailContent = array();
		$mailData = array();
		$mailSections = array();
		$mailHeaders = '';
		
		// check if $mailId is empty
		if (empty($mailId)) {
			$this->error->addError(1, 'SendMailFromQueue() $mailId is invalid', NOTICE_ERROR, $this->displayErrors);
			return false;	
		}
		
		// get email details
		$mailContent = $this->getQueuedEmailDetails($mailId);
		
		// if fetching email data fails - return error
		if (empty($mailContent)) {
			$this->error->addError(1, 'SendMailFromQueue() this email was sent already', NOTICE_ERROR, $this->displayErrors);
			return false;
		}
		
		// get email keywords
		$mailData = $this->getQueuedEmailKeywords($mailId);
		
		// get email sections
		$mailSections = $this->getQueuedEmailSections($mailId);
		
		// Get email
		$mail = $this->getEmail($mailData, $mailContent['mail_type'], $mailContent['variable'], $mailContent['value'], $mailSections);
		
		// Send email
		$mailHeaders .= 'MIME-Version: 1.0'."\r\n";
		$mailHeaders .= 'Content-type: '.$mail['mime_type'].'; charset=iso-8859-1'."\r\n";
		$mailHeaders .= 'From: '.(empty($mailContent['from']) ? $mail['from'] : $mailContent['from'])."\r\n";
		$mailHeaders .= 'Cc: '.$mailContent['cc']."\r\n";
		$mailHeaders .= 'Bcc: '.$mailContent['to']."\r\n";
		$mailHeaders .= 'Reply-To: '.$mailContent['reply_to']."\r\n";
		
		$mailSent = mail($mailContent['to'], $mail['subject'], $mail['body'], $mailHeaders);
		
		// Return true if sending is successful
		if ($mailSent === TRUE) {
			$this->SetSent ($mailId);
			return true;
		}
		else {
			return false;
		}
	}
	
	/**
	 * This method gets email details (TO, CC, BCC, FROM etc.) from the database
	 *
	 * @access   public
	 * @author   Svilen <svilen@svilen.com>
	 *
	 * @param    integer		$mailId	Mail Id indicating the email message id in the queue, for which details should be got
	 *
	 * @return   boolean/array			Returns email details on success or FALSE on fail
	 *
	 * @since    19-09-2005
	 * @version  1.0
	 *
	 */
	function getQueuedEmailDetails($mailId) {
		$mailId = (int) $this->anydb->escapeStr($mailId);
		$mailContent = array();
		
		// check if $mailId is empty
		if (empty($mailId)) {
			$this->error->addError(1, 'getQueuedEmailDetails() $mailId is invalid', NOTICE_ERROR, $this->displayErrors);
			return false;	
		}
		
		// get email details
		$query = <<<echo
SELECT m1.mails_queue_id as mails_queue_id, m1.to_string as to, m1.cc_string as cc, m1.bcc_string as bcc, m1.from_string as from, m1.reply_to_string as reply_to, m1.mail_type as mail_type, m1.variable as variable, m1.value as value
FROM $this->mailsQueueTable m1 WHERE m1.mails_queue_id = $mailId AND m1.sent = FALSE;
echo;
		$this->anydb->query($query);
		$mailContent = $this->anydb->getNext();
		
		// return email details on success
		if (empty($this->anydb->error) && !empty($mailContent)) {
			return $mailContent;
		}
		else {
			return false;
		}
	}
	
	/**
	 * This method gets email keywords from the database
	 *
	 * @access   public
	 * @author   Svilen <svilen@svilen.com>
	 *
	 * @param    integer		$mailId	Mail Id indicating the email message id in the queue, for which keywords should be got
	 *
	 * @return   boolean/array			Returns email keywords on success or FALSE on fail
	 *
	 * @since    19-09-2005
	 * @version  1.0
	 *
	 */
	function getQueuedEmailKeywords($mailId) {
		$mailId = (int) $this->anydb->escapeStr($mailId);
		$mailKeywords = array();
		$mailKeywordsReturn = array();
		
		// check if $mailId is empty
		if (empty($mailId)) {
			$this->error->addError(1, 'getQueuedEmailKeywords() $mailId is invalid', NOTICE_ERROR, $this->displayErrors);
			return false;	
		}
		
		// get email keywords
		$query = <<<echo
SELECT m1.mails_queue_data_id as mails_queue_data_id, m1.mails_queue_id as mails_queue_id, m1.keyword as keyword, m1.value as value
FROM $this->mailsQueueDataTable m1 WHERE m1.mails_queue_id = $mailId;
echo;
		$this->anydb->query($query);
		$mailKeywords = $this->anydb->getAll();
		
		// reduce array to the necessary depth and length
		foreach ($mailKeywords as $key => $value) {
			$mailKeywordsReturn[$value['keyword']]	= $value['value'];
		}
		
		// return email details on success
		if (empty($this->anydb->error)) {
			return $mailKeywordsReturn;
		}
		else {
			$this->error->addError(1, $this->anydb->error, NOTICE_ERROR, $this->displayErrors);
			return false;	
		}
	}
	
	/**
	 * This method gets email XML sections from the database
	 *
	 * @access   public
	 * @author   Svilen <svilen@svilen.com>
	 *
	 * @param    integer		$mailId	Mail Id indicating the email message id in the queue, for which XML sextions should be got
	 *
	 * @return   boolean/array			Returns email XML setions on success or FALSE on fail
	 *
	 * @since    19-09-2005
	 * @version  1.0
	 *
	 */
	function getQueuedEmailSections($mailId) {
		$mailId = (int) $this->anydb->escapeStr($mailId);
		$mailSection = '';
		$mailSections = array();
		
		// check if $mailId is empty
		if (empty($mailId)) {
			$this->error->addError(1, 'getQueuedEmailSections() $mailId is empty', NOTICE_ERROR, $this->displayErrors);
			return false;	
		}
		
		// get email keywords
		$query = <<<echo
SELECT m1.section as section
FROM $this->mailsQueueSectionsTable m1 WHERE m1.mails_queue_id = $mailId;
echo;
		$this->anydb->query($query);
		
		// get all sections
		while ($mailSection = $this->anydb->getValue()) {
			$mailSections[] = $mailSection;	
		}
		
		// return email details on success
		if (empty($this->anydb->error)) {
			return $mailSections;
		}
		else {
			$this->error->addError(1, $this->anydb->error, NOTICE_ERROR, $this->displayErrors);
			return false;	
		}
	}
	
	
	/**
	 * This class method generates the email which should be send
	 *
	 * @access   public
	 * @author   Svilen
	 *
	 * @param    integer   $olderThan  	Set the history days, e.g. how many days before current date mails should be keeped.
	 *
	 * @return   boolean						Returns TRUE if old emails in queue are deleted or FALSE on fail
	 *
	 * @since    19-09-2005
	 * @version  1.0
	 *
	 */
	function DeleteOldMails($olderThan = 7) {
		$olderThan = $this->anydb->escapeStr($olderThan);
		
		$query = <<<echo
DELETE FROM $this->mailsQueueTable WHERE sent = TRUE AND timestamp_sent < (NOW() - interval '$olderThan day');
echo;
		
		$this->anydb->query($query);
		
		if (empty($this->anydb->error)) {
			return true;	
		}
		else {
			return false;	
		}
	}
	
	/**
	 * This class method sets an email message in queue as Sent
	 *
	 * @access   public
	 * @author   Svilen
	 *
	 * @param    integer   $mailId  	Email id in queue, which should be set as Sent
	 *
	 * @return   boolean					Returns TRUE if email in queue is set as Sent or FALSE on fail
	 *
	 * @since    19-09-2005
	 * @version  1.0
	 *
	 */
	function SetSent ($mailId) {
		$mailId = (int) $this->anydb->escapeStr($mailId);
		
		// check if $mailId is empty
		if (empty($mailId)) {
			$this->error->addError(1, 'SetSent() $mailId is empty', NOTICE_ERROR, $this->displayErrors);
			return false;	
		}
		
		// set sent email
		$query = <<<echo
UPDATE $this->mailsQueueTable SET sent = TRUE, timestamp_sent = NOW() WHERE mails_queue_id = $mailId AND sent = FALSE;
echo;
		$this->anydb->query($query);
		
		// return email details on success
		if (empty($this->anydb->error)) {
			return true;
		}
		else {
			$this->error->addError(1, $this->anydb->error, NOTICE_ERROR, $this->displayErrors);
			return false;	
		}
	}
}

?>